import os
from flask import Flask, request, jsonify
from flask_cors import cross_origin
from tensorflow.keras.models import Model
import librosa
import numpy as np
import tensorflow as tf
#import tensorflow.compat.v1 as tf

from tensorflow import keras
#import keras

app = Flask(__name__)


@app.route('/')
def hello_world():
    return 'hello world'


# 注册声音
@app.route('/api/register', methods=['POST'])
@cross_origin()  # 跨域
def register():
    file = request.files.get('file')
    userid = request.form.get('userid')
    check_file(file)
    send_file(file, userid, 'register')
    return jsonify({
        'code': 200,
        'message': "注册成功"
    })


# 注册声音
@app.route('/api/recognize', methods=['POST'])
@cross_origin()  # 跨域
def recognize():
    file = request.files.get('file')
    userid = request.form.get('userid')
    result = check_file(file)
    if result.json['code'] != 200:
        return result
    send_file(file, userid, 'upload')
    person1 = 'register/'+userid+'.wav'
    person2 = 'upload/'+userid+'.wav'
    feature1 = infer(person1, intermediate_layer_model)[0]
    feature2 = infer(person2, intermediate_layer_model)[0]
    # 对角余弦值
    dist = np.dot(feature1, feature2) / (np.linalg.norm(feature1) * np.linalg.norm(feature2))
    if dist > 0.7:
        return jsonify({
            'code': 200
        })
    else:
        return jsonify({
            'code': -1
        })


def check_file(file) -> object:
    if file is None:
        # 表示没有发送文件
        return jsonify({
            'code': -1,
            'message': "没有文件"
        })
    file_name = file.filename  # print(file.filename)
    suffix = os.path.splitext(file_name)[-1]  # 获取文件后缀（扩展名）
    if suffix != '.wav':
        return jsonify({
            'code': -1,
            'message': "不是wav文件"
        })
    return jsonify({
            'code': 200
        })


def send_file(file, userid, folder) -> object:
    file_name = file.filename  # print(file.filename)
    suffix = os.path.splitext(file_name)[-1]  # 获取文件后缀（扩展名）

    basePath = os.path.dirname(__file__)  # 当前文件所在路径print(basePath)
    upload_path = os.path.join(basePath, str(folder))
    if not os.path.exists(upload_path):
        os.makedirs(upload_path)
    upload_path = os.path.join(upload_path, userid)
    upload_path = os.path.abspath(upload_path)  # 将路径转换为绝对路径print("绝对路径：",upload_path)
    file.save(upload_path + str(userid) + suffix)  # 保存文件


# 读取音频数据
def load_data(data_path):
    wav, sr = librosa.load(data_path, sr=16000)
    intervals = librosa.effects.split(wav, top_db=20)
    wav_output = []
    for sliced in intervals:
        wav_output.extend(wav[sliced[0]:sliced[1]])
    assert len(wav_output) >= 8000, "有效音频小于0.5s"
    wav_output = np.array(wav_output)
    ps = librosa.feature.melspectrogram(y=wav_output, sr=sr, hop_length=256).astype(np.float32)
    ps = ps[np.newaxis, ..., np.newaxis]
    return ps


def infer(audio_path, layer_model):
    #with sess.as_default():
        #with graph.as_default():
    data = load_data(audio_path)
    feature = layer_model.predict(data)
    return feature

@app.route('/health', methods=['GET'])
def health():
    return  jsonify({"health": "true"})


if __name__ == '__main__':
    #global graph, sess

    #sess = tf.compat.v1.keras.backend.get_session()
    #graph = tf.compat.v1.get_default_graph()

    layer_name = 'global_max_pooling2d'
    model = tf.keras.models.load_model('models/resnet.h5')
    intermediate_layer_model = Model(inputs=model.input, outputs=model.get_layer(layer_name).output)
    app.run(host="0.0.0.0", port=8080)
